package UIAway
{
	import UIFree.ObjectEvent;
	import UIFree.controls.uif_ebutton;
	import UIFree.uif_component;
	import UIFree.uif_ecomponent;
	
	import UIUtils.uif_util;
	
	import away3d.cameras.lenses.PerspectiveLens;
	import away3d.containers.View3D;
	import away3d.lights.LightBase;
	import away3d.loaders.Loader3D;
	import away3d.loaders.parsers.Max3DSParser;
	import away3d.materials.utils.CubeMap;
	import away3d.primitives.SkyBox;
	import away3d.vf.managers.awayLoadSection;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	
	public class uif_view extends uif_ecomponent {
		private var _view				 : View3D;
		private var _lights				 : Array;
		private var _skyBox				 : SkyBox;
		protected var _renderEnabled	 : Boolean;
		
		private var _ratio				 : Number;
		
		
		public static const CAMERAFREEZE 	: String = 'CAMERAFREEZE';
		public static const RENDERFREEZE 	: String = 'RENDERFREEZE';
		public static const DISPOSE		 	: String = 'DISPOSE';
		public static const SKYBOXCOMPLETE 	: String = 'SKYBOXCOMPLETE';
		
		public function uif_view(parent				:uif_component, 
								 skyBoxFilePattern	: String='', 
								 a_forceMouseMove	: Boolean = true, 
								 rect				: Rectangle=null,
								a_ratio				: Number=1) {
			rect = rect?rect:(new Rectangle(0, 0, parent.app.width, parent.app.height));
			super(parent, rect.x, rect.y, rect.width, rect.height);
			_ratio = a_ratio;

			_renderEnabled = true; 
			Loader3D.enableParser(Max3DSParser);
			var ls: awayLoadSection = new awayLoadSection();
			
			createComponents(a_forceMouseMove);
			initEvents();
			loadResources(skyBoxFilePattern);
			
			ls.endSection(completeLoadResource);
			
		}
		
		public function set ratio(a_ratio: Number): void {
			if (_ratio != a_ratio) {
				setRatio(a_ratio);
			}
		}
		
		public function get ratio(): Number {
			return _ratio;
		}
		
		protected function setRatio(a_ratio: Number): void {
			_ratio 		= a_ratio;
		}
		
		protected function createComponents(a_forceMouseMove: Boolean = true): void {
			_view 			= new View3D();
			_view.width		= width;
			_view.height	= height;
			_view.antiAlias = 4;
			_view.forceMouseMove	= a_forceMouseMove;
			_view.backgroundAlpha 	= 0xFFFFFF;
			
			lights = createLights();
		};
		
		public function get lights(): Array {
			return _lights;
		}
		
		protected function removeLights(): void {
			_lights.forEach(function(light:LightBase, i:int, arr: Array): void {
				_view.scene.removeChild(light);
			});
		}
		
		public function set lights(a_lights: Array): void {
			if (_lights) removeLights();
			_lights = a_lights; 
			if (_lights)
				_lights.forEach(function(light:LightBase, i:int, arr: Array): void {
					_view.scene.addChild(light);
				});
		}
		
		public function Screenshot(size: Point): Bitmap {
			var bitmap: Bitmap = new Bitmap(new BitmapData(size.x, size.y));
			var rect	: Rectangle = uif_util.EnterHere(bitmap.bitmapData.rect, new Point(_view.width, _view.height), false);
			var _tmp	: Bitmap = new Bitmap(new BitmapData(_view.width, _view.height, true, 0x0));
			_tmp.smoothing = true;
			
			_view.renderer.swapBackBuffer = false;
			_view.render();
			_view.stage3DProxy.context3D.drawToBitmapData(_tmp.bitmapData); 
			_view.renderer.swapBackBuffer = true;
			
			var mat		: Matrix = new Matrix();
			mat.scale(rect.width/_view.width, rect.height/_view.height);
			mat.translate(rect.x, rect.y);
			bitmap.bitmapData.draw(_tmp, mat);
			_tmp.bitmapData.dispose();
			
			return bitmap;
		}
		
		protected function initEvents(): void {
			addEventListener(CAMERAFREEZE, doCameraFreeze);
			addEventListener(RENDERFREEZE, doRenderFreeze);
			addEventListener(Event.REMOVED_FROM_STAGE, doRemoveToStage);
		}
		
		protected function removeEvents(): void {
			removeEventListener(CAMERAFREEZE, doCameraFreeze);
			removeEventListener(RENDERFREEZE, doRenderFreeze);
			removeEventListener(Event.REMOVED_FROM_STAGE, doRemoveToStage);
		}
		
		protected function doRemoveToStage(e: Event): void {
			dispose();
		}
		
		protected function doDisposeAway(): void {
			removeEvents();
			dispatchEvent(new Event(DISPOSE));
		}
		
		override public function dispose(): void {
			super.dispose();
			doDisposeAway();	
		}
		
		protected function doCameraFreeze(e: ObjectEvent): void {
			
		}
		
		protected function doRenderFreeze(e: ObjectEvent): void {
			renderEnabled = !(e.object as Boolean); 
		}
		
		public function set renderEnabled(a_set: Boolean): void {
			_renderEnabled = a_set;
		}
		
		public function get renderEnabled(): Boolean {
			return _renderEnabled;
		}
		
		public function get skyBox(): SkyBox {
			return _skyBox;
		}
		
		protected function completeLoadResource(): void {
			if (skyBox) view.scene.addChild(skyBox);
			addChild(_view);
			afterStage(function(): void {
				stage.addEventListener(Event.ENTER_FRAME, enterFrame);
			});
		}
		
		protected function loadResources(skyBoxFilePattern: String=''): void {
			loadSkyBox(skyBoxFilePattern);
		}
		
		protected function disposeSkyBox(): void {
			if (_skyBox) {
				_skyBox.dispose(true);
				_skyBox.material.dispose(true);
			}
			_skyBox = null;
		}
		
		protected function loadSkyBoxComplete(a_skyBox: SkyBox): void {
			disposeSkyBox();
			_skyBox = a_skyBox;
			_view.scene.addChild(_skyBox);
			dispatchEvent(new Event(SKYBOXCOMPLETE));
		}
		
		public function loadSkyBox(skyBoxFilePattern: String=''): void {
			if (skyBoxFilePattern) {
				var ls: awayLoadSection = new awayLoadSection();
				var tmpSkuBox: SkyBox = ls.loadSkyBox(skyBoxFilePattern)
				ls.endSection(function(): void {
					loadSkyBoxComplete(tmpSkuBox);
				});
			} else disposeSkyBox();
		}
		
		protected function enterFrame(e: Event): void {
			if (_renderEnabled) _view.render();
		}
		
		public function get view(): View3D {
			return _view;
		}
		
		protected function createLights(): Array {
			return null;
		}
	}
}